//
//  MGGradientEdgeView.m
//  Mango
//
//  Created by 胡超 on 2021/2/5.
//  Copyright © 2021 DLive. All rights reserved.
//

#import "MGGradientEdgeView.h"
#import "UIView+Mango.h"

@interface MGGradientEdgeView ()
@property (nonatomic,strong) UIScrollView *scrollView;
@property (nonatomic,assign) MGGradientEdgeMode mode;
@property (nonatomic,assign) CGFloat edgeWidth;
@property (nonatomic,assign) BOOL autoHide;

@property (nonatomic,strong) CAGradientLayer *edgeLayer;
@property (nonatomic,assign) CGSize frameSize;

@end

@implementation MGGradientEdgeView

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        
    }
    return self;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    [self.edgeLayer setFrame:self.bounds];
    [self.scrollView setFrame:self.bounds];
    
    if (!CGSizeEqualToSize(self.frameSize, self.size)) {
        [self setFrameSize:self.size];
        [self updateEdgeLayerLocations];
    }
}

- (void)addScrollView:(UIScrollView *)scrollView mode:(MGGradientEdgeMode)mode edgeWidth:(CGFloat)edgeWidth autoHide:(BOOL)autoHide {
    self.scrollView = scrollView;
    self.mode = mode;
    self.edgeWidth = edgeWidth;
    self.autoHide = autoHide;
    
    [scrollView setFrame:self.bounds];
    if (autoHide) {
        [scrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
    }
    [self addSubview:scrollView];
    
    self.edgeLayer = [CAGradientLayer layer];
    self.edgeLayer.frame = self.bounds;
    self.layer.mask = self.edgeLayer;
    
    if (mode >= MGGradientEdgeModeTopBottom) {
        self.edgeLayer.colors = @[
            (id)UIColor.clearColor.CGColor,
            (id)UIColor.whiteColor.CGColor,
            (id)UIColor.whiteColor.CGColor,
            (id)UIColor.clearColor.CGColor,
        ];
    } else {
        self.edgeLayer.colors = @[
            (id)UIColor.clearColor.CGColor,
            (id)UIColor.whiteColor.CGColor,
        ];
    }
    
    switch (mode) {
        case MGGradientEdgeModeTop:
            self.edgeLayer.startPoint = CGPointMake(0, 0);
            self.edgeLayer.endPoint = CGPointMake(0, 1);
            break;
        case MGGradientEdgeModeLeft:
            self.edgeLayer.startPoint = CGPointMake(0, 0);
            self.edgeLayer.endPoint = CGPointMake(1, 0);
            break;
        case MGGradientEdgeModeBottom:
            self.edgeLayer.startPoint = CGPointMake(0, 1);
            self.edgeLayer.endPoint = CGPointMake(0, 0);
            break;
        case MGGradientEdgeModeRight:
            self.edgeLayer.startPoint = CGPointMake(1, 0);
            self.edgeLayer.endPoint = CGPointMake(0, 0);
            break;
        case MGGradientEdgeModeTopBottom:
            self.edgeLayer.startPoint = CGPointMake(0, 0);
            self.edgeLayer.endPoint = CGPointMake(0, 1);
            break;
        case MGGradientEdgeModeLeftRight:
            self.edgeLayer.startPoint = CGPointMake(0, 0);
            self.edgeLayer.endPoint = CGPointMake(1, 0);
            break;
            
        default:
            break;
    }
}

- (void)updateEdgeLayerLocations {
    CGFloat edgeWidthRate = 0;
    switch (self.mode) {
        case MGGradientEdgeModeTop: {
            edgeWidthRate = self.edgeWidth/self.height;
            if (self.scrollView.contentOffset.y <= 0 && self.autoHide) {
                self.edgeLayer.locations = @[@(-edgeWidthRate),@(0),@(1)];
            } else {
                self.edgeLayer.locations = @[@(0),@(edgeWidthRate),@(1)];
            }
            break;
        }
        case MGGradientEdgeModeLeft:
            edgeWidthRate = self.edgeWidth/self.width;
            if (self.scrollView.contentOffset.x <= 0 && self.autoHide) {
                self.edgeLayer.locations = @[@(-edgeWidthRate),@(0),@(1)];
            } else {
                self.edgeLayer.locations = @[@(0),@(edgeWidthRate),@(1)];
            }
            break;
        case MGGradientEdgeModeBottom:
            edgeWidthRate = self.edgeWidth/self.height;
            if (self.scrollView.contentOffset.y+self.scrollView.height >= self.scrollView.contentSize.height && self.autoHide) {
                self.edgeLayer.locations = @[@(-edgeWidthRate),@(0),@(1)];
            } else {
                self.edgeLayer.locations = @[@(0),@(edgeWidthRate),@(1)];
            }
            break;
        case MGGradientEdgeModeRight:
            edgeWidthRate = self.edgeWidth/self.width;
            if (self.scrollView.contentOffset.x+self.scrollView.width >= self.scrollView.contentSize.width && self.autoHide) {
                self.edgeLayer.locations = @[@(-edgeWidthRate),@(0),@(1)];
            } else {
                self.edgeLayer.locations = @[@(0),@(edgeWidthRate),@(1)];
            }
            break;
        case MGGradientEdgeModeTopBottom:
            edgeWidthRate = self.edgeWidth/self.height;
            if (self.scrollView.contentOffset.y <= 0 && self.autoHide) {
                self.edgeLayer.locations = @[@(-edgeWidthRate),@(0),@(1-edgeWidthRate),@(1)];
            } else if (self.scrollView.contentOffset.y+self.scrollView.height >= self.scrollView.contentSize.height && self.autoHide) {
                self.edgeLayer.locations = @[@(0),@(edgeWidthRate),@(1),@(1+edgeWidthRate)];
            } else {
                self.edgeLayer.locations = @[@(0),@(edgeWidthRate),@(1-edgeWidthRate),@(1)];
            }
            break;
        case MGGradientEdgeModeLeftRight:
            edgeWidthRate = self.edgeWidth/self.width;
            if (self.scrollView.contentOffset.x <= 0 && self.autoHide) {
                self.edgeLayer.locations = @[@(-edgeWidthRate),@(0),@(1-edgeWidthRate),@(1)];
            } else if (self.scrollView.contentOffset.x+self.scrollView.width >= self.scrollView.contentSize.width && self.autoHide) {
                self.edgeLayer.locations = @[@(0),@(edgeWidthRate),@(1),@(1+edgeWidthRate)];
            } else {
                self.edgeLayer.locations = @[@(0),@(edgeWidthRate),@(1-edgeWidthRate),@(1)];
            }
            break;
            
        default:
            break;
    }
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(UIScrollView *)scrollView change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    [self updateEdgeLayerLocations];
}

@end
